package com.sztz.design.buildsingleton;

/**
 * 双检锁/双重校验锁单例模式（DCL，即 double-checked locking）
 * @author yzy
 * @date 2022/8/16 16:30
 */
public class DoubleCheckLockPattern {
    /**
     * 静态实例，需要的时候才创建
     */
    private static volatile DoubleCheckLockPattern instance;
    /**
     * 私有的构造方法
     */
    private DoubleCheckLockPattern(){
        /*
         * 反射时会调用构造方法，所以在构造方法中添加判断，
         * 如果对象为null则允许调用，否则抛异常。
         * 这种方式就解决了反射导致单例被破坏的问题
         */
        if(instance!=null){
            throw new RuntimeException();
        }
    }
    /**
     * 双重校验锁单例模式
     * @return DoubleCheckLockPattern
     * @author yzy
     * @date 2022/8/16 16:30
     */
    public static DoubleCheckLockPattern getInstance(){
        if(instance == null){
            synchronized (DoubleCheckLockPattern.class){
                if(instance==null){
                    instance = new DoubleCheckLockPattern();
                }
            }
        }
        return instance;
    }
    /**
     * 解决反序列化破坏单例模式
     * 在反序列化调用readObject方法时底层会判断是否存在readResolve方法，
     * 如果存在则调用readResolve方法。所以在readResolve方法中返回创建的单例
     * @author yzy
     * @date 2022/8/16 16:30
     */
    private Object readResolve() {
        return instance;
    }
}
